#include "audioplayer.h"

AudioPlayer::AudioPlayer(QObject *parent)
    : QObject(parent),
      audioOutput(nullptr),
      playing(false),
      volumeLevel(0.8f),
      muteState(false),
      sampleRate(44100),
      channelCount(2),
      sampleSize(16),
      bufferSize(4096)
{
    // 初始化音频格式
    initAudioFormat();
    
    // 初始化缓冲区
    audioBuffer.setBuffer(&bufferData);
    audioBuffer.open(QIODevice::ReadWrite);
    
    // 初始化缓冲区检查定时器
    bufferTimer.setInterval(20); // 每20ms检查一次缓冲区
    connect(&bufferTimer, &QTimer::timeout, this, &AudioPlayer::checkBuffer);
    
    LOG_INFO("音频播放模块已初始化");
}

AudioPlayer::~AudioPlayer()
{
    stop();
    
    LOG_INFO("音频播放模块已销毁");
}

bool AudioPlayer::start()
{
    if (playing) {
        return true;
    }
    
    // 重置缓冲区
    resetState();
    
    // 创建音频输出对象
    if (audioOutput) {
        delete audioOutput;
    }
    
    audioOutput = new QAudioOutput(audioFormat, this);
    
    // 设置音量
    audioOutput->setVolume(muteState ? 0.0f : volumeLevel);
    
    // 设置缓冲区大小
    audioOutput->setBufferSize(bufferSize);
    
    // 连接状态变化信号
    connect(audioOutput, &QAudioOutput::stateChanged, this, &AudioPlayer::handleStateChanged);
    
    // 开始播放
    audioOutput->start(&audioBuffer);
    
    if (audioOutput->state() != QAudio::ActiveState && audioOutput->state() != QAudio::IdleState) {
        LOG_ERROR("无法启动音频播放");
        emit errorOccurred("无法启动音频播放");
        delete audioOutput;
        audioOutput = nullptr;
        return false;
    }
    
    playing = true;
    bufferTimer.start();
    
    LOG_INFO("音频播放已开始");
    return true;
}

void AudioPlayer::stop()
{
    if (!playing) {
        return;
    }
    
    bufferTimer.stop();
    
    if (audioOutput) {
        audioOutput->stop();
        delete audioOutput;
        audioOutput = nullptr;
    }
    
    resetState();
    
    playing = false;
    
    LOG_INFO("音频播放已停止");
}

bool AudioPlayer::isPlaying() const
{
    return playing;
}

void AudioPlayer::setVolume(float volume)
{
    if (volume < 0.0f) volume = 0.0f;
    if (volume > 1.0f) volume = 1.0f;
    
    volumeLevel = volume;
    
    if (audioOutput && !muteState) {
        audioOutput->setVolume(volumeLevel);
    }
    
    LOG_INFO(QString("音频音量已设置为: %1%").arg(int(volume * 100)));
}

float AudioPlayer::getVolume() const
{
    return volumeLevel;
}

void AudioPlayer::setMuted(bool muted)
{
    muteState = muted;
    
    if (audioOutput) {
        audioOutput->setVolume(muted ? 0.0f : volumeLevel);
    }
    
    LOG_INFO(QString("音频%1").arg(muted ? "已静音" : "已取消静音"));
}

bool AudioPlayer::isMuted() const
{
    return muteState;
}

void AudioPlayer::setAudioFormat(int sampleRate, int channelCount, int sampleSize)
{
    bool needRestart = playing;
    
    if (needRestart) {
        stop();
    }
    
    this->sampleRate = sampleRate;
    this->channelCount = channelCount;
    this->sampleSize = sampleSize;
    
    initAudioFormat();
    
    if (needRestart) {
        start();
    }
    
    LOG_INFO(QString("音频格式已设置为: 采样率=%1, 通道数=%2, 采样位数=%3")
            .arg(sampleRate).arg(channelCount).arg(sampleSize));
}

void AudioPlayer::getAudioFormat(int &sampleRate, int &channelCount, int &sampleSize) const
{
    sampleRate = this->sampleRate;
    channelCount = this->channelCount;
    sampleSize = this->sampleSize;
}

void AudioPlayer::processAudioData(const QByteArray &data)
{
    if (!playing) {
        // 如果还没开始播放，则启动播放
        if (!start()) {
            return;
        }
    }
    
    // 将接收到的数据添加到缓冲区
    qint64 pos = audioBuffer.pos();
    audioBuffer.buffer().append(data);
    
    // 计算合适的播放位置
    qint64 idealPos = audioBuffer.size() - bufferSize * 2;
    if (idealPos < 0) idealPos = 0;
    
    // 如果缓冲区太大，则重置位置以避免延迟
    if (pos < idealPos) {
        audioBuffer.seek(idealPos);
    }
}

void AudioPlayer::handleStateChanged(QAudio::State state)
{
    emit stateChanged(state);
    
    if (state == QAudio::IdleState && playing) {
        // 重新开始播放
        audioOutput->start(&audioBuffer);
    } else if (state == QAudio::StoppedState) {
        if (audioOutput->error() != QAudio::NoError) {
            QString errorString;
            switch(audioOutput->error()) {
            case QAudio::OpenError:
                errorString = "打开音频设备失败";
                break;
            case QAudio::IOError:
                errorString = "音频数据IO错误";
                break;
            case QAudio::UnderrunError:
                errorString = "音频数据不足";
                break;
            case QAudio::FatalError:
                errorString = "音频设备出现致命错误";
                break;
            default:
                errorString = "未知音频错误";
                break;
            }
            
            LOG_ERROR(QString("音频播放错误: %1").arg(errorString));
            emit errorOccurred(errorString);
            
            // 尝试重启
            stop();
            start();
        }
    }
}

void AudioPlayer::checkBuffer()
{
    if (!playing || !audioOutput) {
        return;
    }
    
    // 如果缓冲区太大，裁剪掉旧数据
    if (audioBuffer.size() > bufferSize * 10) { // 超过10倍缓冲区大小
        qint64 currentPos = audioBuffer.pos();
        
        // 保留当前位置附近的数据
        int keepSize = bufferSize * 5; // 保留5倍缓冲区大小
        int keepStart = qMax(qint64(0), currentPos - keepSize / 2);
        
        QByteArray keepData = bufferData.mid(keepStart, keepSize);
        bufferData.clear();
        bufferData.append(keepData);
        
        // 调整位置
        audioBuffer.seek(qMin(currentPos - keepStart, qint64(bufferData.size())));
    }
}

void AudioPlayer::initAudioFormat()
{
    audioFormat.setSampleRate(sampleRate);
    audioFormat.setChannelCount(channelCount);
    audioFormat.setSampleSize(sampleSize);
    audioFormat.setCodec("audio/pcm");
    audioFormat.setByteOrder(QAudioFormat::LittleEndian);
    audioFormat.setSampleType(QAudioFormat::SignedInt);
}

void AudioPlayer::setBufferSize(int size)
{
    bufferSize = size;
    
    if (audioOutput) {
        audioOutput->setBufferSize(bufferSize);
    }
}

void AudioPlayer::resetState()
{
    bufferData.clear();
    audioBuffer.seek(0);
} 